﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Text;
using System.Web.Mvc;
using Common.Background.Models;
using System.IO;
using System.Web.UI;
using System.Web.Compilation;
using EntityFrameworks.Entity.Core;
using System.Web.WebPages;

namespace Common.Background.Helper
{
    public static class ViewHelper
    {
        #region DataTree页面上使用
        public static MvcHtmlString GetDataTree<T>(this HtmlHelper html,
            IEnumerable<T> list,
            string name,
            int[] selectValue,
            int treeID) where T : ITree<T>
        {
            return GetDataTree(html, list, name, selectValue, treeID, null);
        }

        public static MvcHtmlString GetDataTree<T>(this HtmlHelper html,
           IEnumerable<T> list,
           string name,
           int[] selectValue,
           int treeID,
           string controller) where T : ITree<T>
        {
            return GetDataTree(html, list, name, selectValue, treeID, true, controller);
        }

        public static MvcHtmlString GetDataTree<T>(this HtmlHelper html,
            IEnumerable<T> list,
            string name,
            int[] selectValue,
            int treeID,
            bool radioButton,
            string controller) where T : ITree<T>
        {
            return MvcHtmlString.Create(new DataTree<T>(list).CreateDataTree(name, selectValue, treeID, radioButton, controller, true));
        }

        public static MvcHtmlString GetDataTree<T>(this HtmlHelper html,
         IEnumerable<T> list,
         string name,
         int[] selectValue,
         int treeID,
         bool radioButton,
         string controller,
         bool displayButton) where T : ITree<T>
        {
            return MvcHtmlString.Create(new DataTree<T>(list).CreateDataTree(name, selectValue, treeID, radioButton, controller, displayButton));
        }
        public static MvcHtmlString GetDataTree<T>(this HtmlHelper html,
            IEnumerable<T> list,
            string name,
            int selectValue,

            string controller) where T : ITree<T>
        {
            return GetDataTree(html, list, name, new int[] { selectValue }, controller);
        }
        public static MvcHtmlString GetDataTree<T>(this HtmlHelper html,
          IEnumerable<T> list,
          string name,
          int[] selectValue,
          string controller) where T : ITree<T>
        {
            return GetDataTree(html, list, name, selectValue, true, controller);
        }
        public static MvcHtmlString GetDataTree<T>(this HtmlHelper html,
           IEnumerable<T> list,
           string name,
           int[] selectValue,
           bool radioButton,
           string controller) where T : ITree<T>
        {
            var MenuRoot = list.FirstOrDefault(i => i.Level == 0);

            return GetDataTree(html, list, name, selectValue, MenuRoot == null ? 1 : MenuRoot.ID, radioButton, controller);
        }

        public static MvcHtmlString GetDataTree<T>(this HtmlHelper html,
          IEnumerable<T> list,
          string name,
          int selectValue,
          int treeID) where T : ITree<T>
        {
            return GetDataTree(html, list, name, new int[] { selectValue }, treeID, null);
        }
        #endregion

        #region DataTree代码层使用
        public static string GetDataTree<T>(IEnumerable<T> list,
         string name,
         int selectValue,
         int treeID,
         string controller) where T : ITree<T>
        {
            return new DataTree<T>(list).CreateDataTree(name, selectValue, treeID, controller);
        }

        public static string GetDataTree<T>(IEnumerable<T> list,
         string name,
         int selectValue,
         int treeID) where T : ITree<T>
        {
            return GetDataTree(list, name, selectValue, treeID, null);
        }
        #endregion

        #region GetDeptTree
        /// <summary>
        /// 树型结构的部门列表
        /// </summary>
        /// <param name="html"></param>
        /// <param name="name"></param>
        /// <param name="selectValue"></param>
        /// <param name="displayButton"></param>
        /// <returns></returns>
        public static MvcHtmlString GetDeptTree(this HtmlHelper html, string name, int? selectValue, string controller)
        {
            var Root = new BackgroundBase<WebDepartments>().GetModel().FirstOrDefault();
            return selectValue.HasValue
               ? MvcHtmlString.Create(new DeptTree().CreateDataTree(name
               , selectValue.Value
               , Root == null ? 1 : Root.ID
               , controller))
           : GetDeptTree(html, name, controller);
        }

        /// <summary>
        /// 树型结构的部门列表
        /// </summary>
        /// <param name="html"></param>
        /// <param name="selectValue"></param>
        /// <param name="displayButton"></param>
        /// <returns></returns>
        public static MvcHtmlString GetDeptTree(this HtmlHelper html, string name, string controller)
        {
            return GetDeptTree(html, name, -1, controller);
        }

        #endregion

        #region 面包屑导航
        /// <summary>
        ///  建立一个站点地图,面包屑导航
        /// </summary>
        /// <param name="html"></param>
        /// <param name="id"></param>
        /// <param name="activeCss"></param>
        /// <param name="urlParams"></param>
        /// <returns></returns>
        public static MvcHtmlString CreateSiteMapTree(
          this HtmlHelper html,
          object id,
          string activeCss)
        {
            return CreateSiteMapTree(html, id, activeCss, null);
        }
        /// <summary>
        /// 建立一个站点地图,面包屑导航
        /// </summary>
        /// <param name="?"></param>
        /// <param name="activeCss"></param>
        /// <returns></returns>
        public static MvcHtmlString CreateSiteMapTree(
            this HtmlHelper html,
            object id,
            string activeCss,
            params string[] urlParams)
        {
            if (id == null)
                return null;
            int _id = Convert.ToInt32(id);
            BreadcrumbNavigation.Init();
            Tree tree = new Tree(BreadcrumbNavigation.Data);
            if (tree == null)
                return null;
            var entity = tree.GetAllFather(_id);
            entity.IsCurrent = true;
            StringBuilder result = new StringBuilder();


            FillFatherTree(result, entity, activeCss, true, urlParams);
            result.Insert(0, "<div class='lx_indexcen_subnav'>");
            result.Append("</div>");
            return MvcHtmlString.Create(result.ToString());
        }

        static void FillFatherTree(StringBuilder result, BreadcrumbNavigation tree, string activeCss, bool isHtml, params string[] urlParams)
        {
            if (tree != null)
            {
                if (isHtml)
                {
                    result.Insert(0, string.Format("<a href='{0}' title='{1}' class='{2}'>{1}</a>"
                        , urlParams == null ? tree.LinkUrl : string.Format(tree.LinkUrl, urlParams)
                         , tree.Name
                         , tree.IsCurrent ? activeCss : string.Empty));
                }
                else
                {
                    result.Append(tree.Name + "-");
                }
                FillFatherTree(result, tree.Father, activeCss, isHtml);
            }
        }

        /// <summary>
        /// 通过站点地址，构造一个网页标题
        /// </summary>
        /// <param name="id"></param>
        /// <returns></returns>
        public static MvcHtmlString CreateTitleFromSiteMap(object id)
        {
            if (id == null)
                return null;
            int _id = Convert.ToInt32(id);
            BreadcrumbNavigation.Init();
            Tree tree = new Tree(BreadcrumbNavigation.Data);
            if (tree == null)
                return null;
            var entity = tree.GetAllFather(_id);
            entity.IsCurrent = true;
            StringBuilder result = new StringBuilder();
            FillFatherTree(result, entity, null, false);
            result.Remove(result.Length - 1, 1);
            return MvcHtmlString.Create(result.ToString());
        }
        #endregion

        #region PartialView扩展

        #region 为页面提供的
        public static string RenderPartialToString(this HtmlHelper htmlHelper, string partial)
        {
            return RenderPartialToString(htmlHelper, partial, null);
        }
        /// <summary>
        /// 将指定ascx分部视图的文本内容追加到当前输出流
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="partial">ascx路径</param>
        /// <returns></returns>
        public static string RenderPartialToString(this HtmlHelper htmlHelper, string partial, object model)
        {
            var viewInstance = BuildManager.CreateInstanceFromVirtualPath(partial, typeof(object));
            ViewDataDictionary vd = new ViewDataDictionary(model);
            var control = viewInstance as ViewUserControl;
            control.ViewContext = htmlHelper.ViewContext;
            control.ViewData = vd;// htmlHelper.ViewData;//得到当前viewcontext中的Model
            Page page = new ViewPage();
            page.Controls.Add(control);
            TextWriter writer = new StringWriter();
            htmlHelper.ViewContext.HttpContext.Server.Execute(page, writer, false);
            return writer.ToString();
        }
        #endregion

        #region 为代码层提供的
        /// <summary>
        /// 返回指定ascx分部视图的文本内容
        /// 如果在页面上输出解释后的ＨＴＭＬ，请使用Html.Decode()
        /// </summary>
        /// <param name="partial">ascx路径</param>
        /// <param name="model">视图模型数据</param>
        /// <returns></returns>
        public static string RenderPartialToString(ControllerContext context, string partial, object model)
        {
            ViewEngineResult result = ViewEngines.Engines.FindPartialView(context, partial);
            if (result.View != null)
            {
                ViewDataDictionary vd = new ViewDataDictionary(model);
                StringBuilder sb = new StringBuilder();
                using (StringWriter sw = new StringWriter(sb))
                {
                    using (HtmlTextWriter output = new HtmlTextWriter(sw))
                    {
                        ViewContext viewContext = new ViewContext(context, result.View, vd, new TempDataDictionary(), output);
                        result.View.Render(viewContext, output);
                    }
                }
                return sb.ToString();
            }

            return String.Empty;

        }
        /// <summary>
        ///  返回指定ascx分部视图的文本内容
        /// </summary>
        /// <param name="partial">ascx路径</param>
        /// <returns></returns>
        public static string RenderPartialToString(ControllerContext context, string partial)
        {
            return RenderPartialToString(context, partial, null);
        }
        #endregion

        #endregion

        #region 页面代码块级权限设计
        /// <summary>
        /// 页面代码块级权限设计
        /// </summary>
        /// <param name="htmlHelper"></param>
        /// <param name="role">角色ID</param>
        /// <param name="template"></param>
        /// <returns></returns>
        public static HelperResult AuthorityHtmlTags(this HtmlHelper htmlHelper,
         OperatorAuthority operatorAuthority,
         Func<string, HelperResult> template)
        {
            var httpContext = htmlHelper.ViewContext.RequestContext.HttpContext;
            var _operatorAuthority = (OperatorAuthority)(httpContext.Session["OperatorAuthority"] == null
                ? 0
                : Convert.ToInt32(httpContext.Session["OperatorAuthority"]));

            if ((_operatorAuthority & operatorAuthority) == operatorAuthority)
                return new HelperResult(writer =>
                {
                    writer.Write(template.Invoke(null));
                });
            return null;
        }


        #endregion
    }
}